package com.cxf.windex.biz;

import com.alibaba.fastjson.JSON;
import com.cxf.windex.base.bean.LockInfo;
import com.cxf.windex.base.biz.BaseBiz;
import com.cxf.windex.base.common.ServiceException;
import com.cxf.windex.base.constant.LockConstant;
import com.cxf.windex.base.constant.UserConstant;
import com.cxf.windex.base.msg.ObjectRestResponse;
import com.cxf.windex.base.secruity.JwtTokenUtil;
import com.cxf.windex.base.secruity.JwtUser;
import com.cxf.windex.base.secruity.JwtUserFactory;
import com.cxf.windex.base.util.EncryptUtil;
import com.cxf.windex.base.util.IdUtil;
import com.cxf.windex.base.util.MD5Util;
import com.cxf.windex.base.util.WxUtil;
import com.cxf.windex.entity.JsTech;
import com.cxf.windex.entity.JsUser;
import com.cxf.windex.enums.StatusEnum;
import com.cxf.windex.enums.TypeEnum;
import com.cxf.windex.mapper.JsUserMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * @author chenxf
 * @date 3/15/2018
 * @description
 */
@Service
public class JsUserBiz  extends BaseBiz<JsUserMapper, JsUser> {
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private JsTechBiz jsTechBiz;

    @Value("${weixin.appid}")
    private String appid;
    @Value("${weixin.secret}")
    private String secret;


    /**
     * 后台登陆
     * @param username 用户名
     * @param password 密码
     * @return
     */
    public Map adminLogin(String username, String password) {
        Map<String, Object> resultMap = new HashMap<String, Object>(4);
        JsUser queryEntity = new JsUser();
        queryEntity.setUsername(username);
        JsUser entity = selectOne(queryEntity);
        if (entity == null) {
            throw new ServiceException("用户不存在");
        }
        if (!EncryptUtil.decrypt(entity.getPassword()).equals(password)) {
            throw new ServiceException("密码不正确");
        }
        resultMap.put("token",
                this.setCurrentUserName(entity));
        return resultMap;
    }

    /**
     * 小程序 code或者openid登陆
     * @param code
     * @param openid
     * @return
     */
    public Map login(String code, String openid,String appid,String secret) {
        Map<String, Object> resultMap = new HashMap<String, Object>(4);
        if (StringUtils.isBlank(openid)) {
            //获取openId
            resultMap.putAll(WxUtil.getOpenId(appid, secret, code));
            if (resultMap.get("errcode") != null && StringUtils.isNotBlank(resultMap.get("errcode").toString())) {
                throw new ServiceException("获取openid失败，错误码：" + resultMap.get("errcode"));
            }
            openid = resultMap.get("openid").toString();
        }
        JsUser entity = new JsUser();
        entity.setOpenid(openid);
        entity = selectOne(entity);
        if (entity == null) {
            resultMap.put("msg","用户不存在");
            return resultMap;
        }

        resultMap.put("token", this.setCurrentUserName(entity));
        return resultMap;
    }

    /**
     * 设置支付密码
     * @param password 支付密码
     * @param openid openid
     * @param  oldPassword 旧支付密码
     * @return
     */
    public void setPassword(String openid,String password,String oldPassword){
        JsUser jsUser=queryByOpenid(openid);
        boolean checked=true;
        if(StringUtils.isNotBlank(oldPassword)){
            if(!EncryptUtil.encrypt(oldPassword).equals(jsUser.getPassword())){
                checked=false;
            }
        }
        if(!checked){
            throw new ServiceException("旧密码不正确");
        }
        if(StringUtils.isBlank(password)){
            throw new ServiceException("请填写新密码");
        }
        updateSelectiveById(JsUser.builder().id(jsUser.getId()).password(EncryptUtil.encrypt(password)).build());
    }

    /**
     * 验证支付密码
     * @param password 支付密码
     * @param openid openid
     * @return
     */
    public void checkPassword(String openid,String password){
        JsUser jsUser=queryByOpenid(openid);
        boolean checked=true;
        if(StringUtils.isNotBlank(password)){
            if(!EncryptUtil.encrypt(password).equals(jsUser.getPassword())){
                checked=false;
            }
        }
        if(!checked){
            throw new ServiceException("支付密码不正确");
        }
    }

    public JsUser queryByOpenid(String openid) {
        JsUser entity = new JsUser();
        entity.setOpenid(openid);
        return selectOne(entity);
    }

    /**
     * 解密手机号码
     * @param encryptedData
     * @param iv
     * @param sessionKey
     * @param id 用户ID
     * @return
     * @throws Exception
     */
    public Map decryptPhone(String encryptedData, String iv, String sessionKey,String id) throws Exception {
        if (StringUtils.isBlank(encryptedData) || StringUtils.isBlank(iv) || StringUtils.isBlank(sessionKey)) {
            throw new ServiceException("请传入encryptedData和IV和sessionKey");
        }

        Map<String, Object> resultMap = (Map<String, Object>) JSON.parseObject(EncryptUtil.decrypt(sessionKey, iv, encryptedData), Map.class);

        if (id != null && StringUtils.isNotBlank(id)) {
            JsUser user = new JsUser();
            user.setId(id);
            user.setMobile(resultMap.get("phoneNumber").toString());
            user.setUsername(resultMap.get("phoneNumber").toString());
            updateSelectiveById(user);
        }
        return resultMap;
    }

    /**
     * 注册用户
     * @param entity
     * @return
     */
    public Map register(JsUser entity){
        Map<String,Object> resultMap=new HashMap<String, Object>(4);
        LockInfo lockInfo = new LockInfo(LockConstant.HASH_LOCK + entity.getOpenid());
        try {
            JsUser user=queryByOpenid(entity.getOpenid());
            if(user!=null){
                lockInfo.unlock();
                resultMap.put("token", this.setCurrentUserName(user));
                resultMap.put("openid",entity.getOpenid());
                return resultMap;
            }
            entity.setId(new IdUtil(5,1).nextId()+"");
            entity.setStatus(StatusEnum.APPLY.getKey());
            entity.setType(TypeEnum.GUEST.getKey());
            if(StringUtils.isNotBlank(entity.getInviter())){
                entity.setCrtUser(entity.getInviter());
            }

            insertSelective(entity);
            resultMap.put("token", this.setCurrentUserName(entity));
            resultMap.put("openid",entity.getOpenid());
        } catch (Throwable throwable) {
            lockInfo.unlock();
            throw new ServiceException(throwable.getMessage());
        } finally {
            lockInfo.unlock();
        }
        return resultMap;
    }

    /**
     * 返回支付结果
     * @param return_msg
     * @param result_code
     * @param openid
     */
    public void pay(String return_msg,String result_code,String openid){
        if(result_code==null||!result_code.equals(UserConstant.SUCCESS)){
            throw new ServiceException(return_msg);
        }

        JsUser entity=new JsUser();
        entity.setOpenid(openid);
        JsUser user= selectOne(entity);
        if(user==null){
            throw new ServiceException("用户不存在");
        }
        entity.setId(user.getId());
        entity.setType(TypeEnum.VIP.getKey());
        //entity.setStatus(StatusEnum.PAYSUCCESS.getKey());
        updateSelectiveById(entity);
    }

    /**
     * 通过旧密码 修改新密码
     * @param password 旧密码
     * @param newPassword 新密码
     * @param newPassword2 新密码确认
     * @param id 用户ID
     */
    public void pwd(String password,String newPassword,String newPassword2,String id){
        if(StringUtils.isBlank(password)){
            throw new ServiceException("密码不能为空");
        }
        if(StringUtils.isBlank(newPassword)){
            throw new ServiceException("新密码不能为空");
        }
        if(StringUtils.isBlank(newPassword2)){
            throw new ServiceException("重复新密码不能为空");
        }
        if(!newPassword.equals(newPassword2)){
            throw new ServiceException("重复新密码与新密码不相同");
        }
        JsUser user=selectById(id);
        if(user==null){
            throw new ServiceException("用户不存在");
        }
        if(!EncryptUtil.decrypt(user.getPassword()).equals(password)){
            throw new ServiceException("密码不正确");
        }
        JsUser pwduser=new JsUser();
        pwduser.setId(user.getId());
        pwduser.setPassword(EncryptUtil.encrypt(newPassword));
        updateSelectiveById(pwduser);
    }

    private String setCurrentUserName(JsUser user) {
        JwtUser userDetails = JwtUserFactory.create(user);

        String token = jwtTokenUtil.generateToken(userDetails);
        UsernamePasswordAuthenticationToken upToken = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(), userDetails.getAuthorities()); // 进行安全认证
        upToken.setDetails(userDetails);
        SecurityContextHolder.getContext().setAuthentication(upToken);
        return token;
    }
}
